/*
 * @Author: zhang zhijiang 2824735304@qq.com
 * @Date: 2024-12-05 20:34:46
 * @LastEditors: zhang zhijiang 2824735304@qq.com
 * @LastEditTime: 2024-12-06 21:25:39
 * @FilePath: /linux/test_12_3/test_12_5/processpoll.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include"task.hpp"
#include<iostream>
#include<unistd.h>
#include<string.h>
#include<vector>
#include <sys/types.h>     
  #include <sys/types.h>
       #include <sys/wait.h>
#include<time.h>
#define processnum  5
using namespace std;
vector<task_t> tasks;
class channel{

public:
 channel(int pipefd,int pid,const string & processname )
 :_pipefd(pipefd),_pid(pid),_processname(processname)
 {}
 public:
int _pipefd;
int _pid;
string _processname;
};
void slaver()
{
   
    while(true)
    {
         int cmdcode = 0;
        int n = read(0,&cmdcode,sizeof(int));//读取任务码
        if(n == sizeof(int))
        {
            //执行代码
            // switch (cmdcode)
            // {
            // case 1 :
                
            //     break;
            
            // default:
            //     break;
            // }
            cout<<"child had saved the new task";
            cout<<getpid()<<":"<<cmdcode<<endl;
             tasks[cmdcode]();
        }
        if(n==0)
        {
            cout<<"process end"<<endl;
            break;
        }
    }

}
void debug(const vector<channel>& channels)
{
     for(const auto e:channels)
    {
        cout<<e._pipefd<<" "<<e._pid<<" "<<e._processname<<endl;
   }
}
void initchannels(vector<channel> *channels,vector<int> & oldfd)
{
    
     for(int i =0;i<processnum;i++)
    {
       
        int pipefd[2];
        int n = pipe(pipefd);
        pid_t id = fork();
        if(id==0)//读
        {
             for(auto e:oldfd)
        {
            close(e);
        }
            close(pipefd[1]);
            dup2(pipefd[0],0);//让子进程读取时只从管道中读取，而不是从标准输入中读取。
            slaver();
            exit(1);
        }
        //写
        close(pipefd[0]);
        channels->push_back(channel(pipefd[1],id,"process-"+to_string(i+1)));
        oldfd.push_back(pipefd[1]);
    }
   
}

 void send(int pipefd,int cmdcode)
 {
    write(pipefd,&cmdcode,sizeof(cmdcode));
 }
 void quit(const vector<channel> &channels)
 {
    
    // for(int i = channels.size()-1;i>=0;i--)//反向关闭管道
    // {

        
    //     close(channels[i]._pipefd);
    //     waitpid(channels[i]._pid,nullptr,0);
    // } 
    for(auto e:channels)
    {
         close(e._pipefd);
        waitpid(e._pid,nullptr,0);
    }
     
 }
int main()
{
    
    vector<int> oldfd;
    loadtasks(&tasks);
    srand(time(nullptr)&getpid());
    vector<channel> channels;
   //1.初始化
   initchannels(&channels,oldfd);
   debug(channels);
    //2. 控制子进程
    for(int i = 0;i<10;i++)//发送一百个任务
    {
        int pipefd  = rand()%processnum+4;
        int cmdcode = rand()%4;
        send(pipefd,cmdcode);
        cout<<"father had send the new task:"<<cmdcode<<endl;
       
        sleep(1);
    }
        //hello 
   //3. 收尾
   quit(channels);
    return 0;
}